 ///
 /// @file    FunctionObj3.cc
 /// @author  lemon(haohb13@gmail.com)
 /// @date    2023-04-27 15:09:48
 ///
 
#include <iostream>
#include <functional>
using std::cout;
using std::endl;
using std::function;

void print()
{	cout << "print()" << endl;	}

void display()
{	cout << "display()" << endl;	}

typedef void(*func)();

struct Foo
{
	void print()
	{	cout << "Foo::print()" << endl;	}

	void display(int x)
	{	cout << "Foo::display() x:" << x << endl; }

	void show(int x, int y)
	{
		cout << "Foo::show() x:" << x  << ", y:" << y << endl;
	}

};

void show(int x, int y)
{
	cout << "show() x:" << x  << ", y:" << y << endl;
}

void test1()
{
	//由于std::bind可以改变函数的参数个数，
	//因此也称为函数适配器
	//
	//使用占位符 std::placeholders::_1
	using namespace std::placeholders;
	std::function<void(int)> f = std::bind(show, 10, _1);
	f(20);

	f = std::bind(show, _1, 10);
	f(20);


	std::function<void(int,int)> f2 = show;
	f2(11, 12);

	//当bind使用占位符时，占位符的数字代表的是参数传递时
	//实参的位置, 占位符本身所在的位置代表的是形参的位置
	f2 = std::bind(&Foo::show, Foo(), _2, _1);
	f2(22, 23);
}
 
void test0() 
{
	func f0 = print;
	function<void()> f = print;
	f();

	f = display;
	f();

	f = f0;
	f();

	//对于成员函数的this指针，需要提前绑定过去
	//
	//对于this指针的位置，可以绑定对象，也可以绑定指针
	f = std::bind(&Foo::print, Foo());
	f();
	
	Foo * fp = nullptr;
	f = std::bind(&Foo::print, fp);
	f();

	f = std::bind(&Foo::display, Foo(), 1);
	f();

	f = std::bind(show, 10, 20);
	f();
} 
 
int main(void)
{
	test0();
	/* test1(); */
	return 0;
}
